package com.ming.easyDevelop.controller.advice;

import com.ming.easyDevelop.utils.CommonResponseCodeEnum;
import com.ming.easyDevelop.entity.vo.ResponseVo;
import com.ming.easyDevelop.controller.base.BaseController;
import com.ming.easyDevelop.exception.BusinessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.net.BindException;

@RestControllerAdvice
public class GlobalExceptionHandlerController extends BaseController {
    private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandlerController.class);

    @ExceptionHandler(value = BusinessException.class)
    public ResponseVo<Object> businessExceptionHandler(BusinessException e, HttpServletRequest request){
        return printLogInfo(STATUS_ERROR,e);
    }
    @ExceptionHandler(value = Exception.class)
    public ResponseVo<Object> handler(Exception e, HttpServletRequest request){
        CommonResponseCodeEnum codeEnum;
        if(e instanceof NoHandlerFoundException){
            //404
            codeEnum = CommonResponseCodeEnum.NOT_FOUND;
        } else if (e instanceof BindException) {
            //類型錯誤
            codeEnum = CommonResponseCodeEnum.TYPE_ERROR;
        } else if (e instanceof DuplicateKeyException) {
            //數據庫主鍵重複
            codeEnum = CommonResponseCodeEnum.DUPLICATE_KEY_ERROR;
        } else {
            codeEnum = CommonResponseCodeEnum.SERVER_ERROR;
        }
        return printLogInfo(codeEnum,STATUS_ERROR,e);
    }

    /**
     * 通用版
     * @param codeEnum
     * @param status
     * @param e
     * @return
     */
    private ResponseVo<Object> printLogInfo(CommonResponseCodeEnum codeEnum,String status,Exception e){
        ResponseVo<Object> result = new ResponseVo<>();
        result.setMessage(codeEnum.getMessage());
        result.setCode(codeEnum.getCode());
        result.setStatus(STATUS_ERROR);
        logger.error("[System Error] {}! Exception:{} ,Exception message:{} ,Exception code:{}",status,e.getClass(),e.getMessage()==null?codeEnum.getMessage():e.getMessage(),codeEnum.getCode());
        return result;
    }

    /**
     * business特供版
     * @param status
     * @param e
     * @return
     */
    private ResponseVo<Object> printLogInfo(String status,BusinessException e){
        return printLogInfo(CommonResponseCodeEnum.getEnumByCode(e.getCode()),STATUS_ERROR,e);
    }
}
